// === ANGLE 指标 ===
// 计算三类角度：
// 1️⃣ K线角度（两天收盘价）
// 2️⃣ 布林带角度（上轨两天）
// 3️⃣ KD角度（两天K值）

function calcVisualAngle(v1, v2, days = 1, xScale = 15, yScale = 7.5) {
    const slope = ((v2 - v1) * yScale) / (days * xScale);
    return Math.atan(slope) * 180 / Math.PI;
}

// === KDJ 计算函数（保持与原逻辑一致） ===
function getMaxMin(slice, high, low) {
    let max = slice[0][high];
    let min = slice[0][low];
    slice.forEach(data => {
        max = Math.max(max, data[high]);
        min = Math.min(min, data[low]);
    });
    return [max, min];
}

function calcKDJ(dataList) {
    const kdjr = [];
    for (let i = 0; i < dataList.length; i++) {
        const kdj = {};
        const close = dataList[i].close;
        if (i >= 8) {
            const [hn, ln] = getMaxMin(dataList.slice(i - 8, i + 1), 'high', 'low');
            const rsv = ((close - ln) / (hn - ln === 0 ? 1 : hn - ln)) * 100;
            kdj.k = (100 + rsv) / 3;
            kdj.d = (100 + kdj.k) / 3;
        } else {
            kdj.k = 50; // 初始化
            kdj.d = 50;
        }
        kdjr.push(kdj);
    }
    return kdjr;
}

// === 计算布林带（仅中轨与上轨） ===
function calcBoll(dataList, period = 20, multiplier = 2) {
    const result = [];
    for (let i = 0; i < dataList.length; i++) {
        if (i < period) {
            result.push({ mid: null, upper: null });
            continue;
        }
        const slice = dataList.slice(i - period, i);
        const closes = slice.map(d => d.close);
        const avg = closes.reduce((a, b) => a + b, 0) / closes.length;
        const variance = closes.reduce((a, b) => a + Math.pow(b - avg, 2), 0) / closes.length;
        const std = Math.sqrt(variance);
        result.push({
            mid: avg,
            upper: avg + multiplier * std
        });
    }
    return result;
}

// === 主体指标 ===
const angleIndicator = {
    name: 'ANGLE',
    shortName: 'ANGLE',
    calcParams: [20],
    figures: [
        { key: 'klineAngle', title: 'K线角度', type: 'line' },
        { key: 'bollAngle', title: '布林角度', type: 'line' },
        { key: 'kAngle', title: 'K角度', type: 'line' }
    ],
    calc: (dataList, indicator) => {
        const results = [];
        const kdj = calcKDJ(dataList);
        const boll = calcBoll(dataList, indicator.calcParams[0]);

        for (let i = 0; i < dataList.length; i++) {
            const result = { klineAngle: null, bollAngle: null, kAngle: null };
            if (i < 1) {
                results.push(result);
                continue;
            }

            // === 1️⃣ K线角度 ===
            const prevClose = dataList[i - 1].close;
            const currClose = dataList[i].close;
            result.klineAngle = calcVisualAngle(prevClose, currClose, 1, 15, 7.5);

            // === 2️⃣ 布林带上轨角度 ===
            const prevBoll = boll[i - 1]?.upper;
            const currBoll = boll[i]?.upper;
            if (prevBoll && currBoll)
                result.bollAngle = calcVisualAngle(prevBoll, currBoll, 1, 15, 7.5);

            // === 3️⃣ K角度 ===
            const prevK = kdj[i - 1].k;
            const currK = kdj[i].k;
            result.kAngle = calcVisualAngle(prevK, currK, 1, 15, 1.5);

            results.push(result);
        }
        return results;
    }
};

export default angleIndicator;
